console.log("webrtcPhone say hello ");
(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
      typeof define === 'function' && define.amd ? define( ["jquery"], factory):
          (global.webrtcPhone = factory());
}(this, function () {
  var serverUrl,
      wssUrl,
      udpUrl,
      stunServers,
      name,
      exten,
      password,
      txtPrivateIdentity,
      txtPublicIdentity,
      autoAnswer,
      oConfigCall,
      oConfigSendMessage,
      sipStack,
      callSession,
      oSipSessionTransferCall,
      registerSession;
  var self;
  function webrtcPhone() {

    self = this;
    this.init = function(data) {
      console.log('web-init--2--', data)
        serverUrl = data.serverUrl;
        name = data.name;
        exten = data.exten;
        password = data.password;
        txtPrivateIdentity = exten;
        txtPublicIdentity = 'sip:' + exten + '@' + serverUrl;
      if (!SIPml.isInitialized()) {
        serverUrl = data.serverUrl;
        name = data.name;
        exten = data.exten;
        password = data.password;
        wssUrl = data.wssUrl;
        udpUrl = data.udpUrl;
        stunServers = data.stunServers;
        autoAnswer = data.autoAnswer;
        txtPrivateIdentity = exten;
        txtPublicIdentity = 'sip:' + exten + '@' + serverUrl;
        wssUrl = 'wss://' + wssUrl;
        udpUrl = 'udp://' + udpUrl;
        stunServers = [{ url: 'stun:'+stunServers+''}];
        SIPml.init(engineErrorCb);
        oConfigSendMessage = {
          events_listener: {events: '*', listener: onSipEventSession}
        };
        var audioRemote = document.getElementById("audio_remote");
        oConfigCall = {
          video_local: null,
          video_remote: null,
          audio_remote: audioRemote,
          screencast_window_id: 0x00000000, // entire desktop
          bandwidth: { audio: undefined, video: undefined },
          video_size: { minWidth: undefined, minHeight: undefined, maxWidth: undefined, maxHeight: undefined },
          events_listener: {events: '*', listener: onSipEventSession},
          sip_caps: [
            {name: '+g.oma.sip-im'},
            {name: 'language', value: '\"en,fr\"'}
          ]
        };

      }
    }



    this.login = function() {
      createSipStack();
    }

    this.register = function() {
      if(sipStack){
        registerSession = sipStack.newSession('register', {
          expires: 200,
          events_listener: {
            events: '*',
            listener: onSipEventSession
          },
          sip_caps: [
            {name: '+g.oma.sip-im', value: null},
            //{ name: '+sip.ice' }, // rfc5768: FIXME doesn't work with Polycom TelePresence
            {name: '+audio', value: null},
            {name: 'language', value: '\"en,fr\"'}
          ]
        });
        registerSession.register();
      }
    }


    this.logout = function() {
      if (sipStack) {
        sipStack.stop();
        sipStack = null;
        callSession = null;
        registerSession = null;
      }
    }


    this.call = function(phoneNumber) {
      if (sipStack && !callSession) {
        callSession = sipStack.newSession('call-audio', oConfigCall);
        callSession.call('sip:' + phoneNumber + '@' + serverUrl);
      }
    }

    this.callAudioVideo = function(to) {
      callSession = sipStack.newSession('call-audiovideo', oConfigCall);
      callSession.call('sip:' + to + '@' + server);
    }

    this.answer = function(e) {
      console.log('webrtc-phone的answer方法', callSession, oConfigCall)
      if (callSession) {
        callSession.accept(oConfigCall);
      }
    }

    this.hangup = function(e) {
      if (callSession) {
        //callSession.reject();
        callSession.hangup({events_listener: {events: '*', listener: onSipEventSession}});
      }
    }

    /**
     * 开始静音 结束静音
     * @param bMute true false
     */
    // Mute OR Unmute the call
    this.sipToggleMute = function(bMute) {
      if (callSession) {
        var i_ret;
        /*could be 'video'*/
        i_ret = callSession.mute('audio', bMute);
        if (i_ret != 0) {
          return;
        }
        callSession.bMute = bMute;
      }
    }

    this.stopStack = function(e) {
      if (sipStack) {
        sipStack.stop();
        sipStack = null;
        callSession = null;
      }
    }

    this.onEvent = function (event) {

    }

    this.sipSendDTMF = function(c) {
      console.log('webrtc-----phone---', c, callSession)
      if (callSession && c) {
        callSession.dtmf(c)
        // if (callSession.dtmf(c) == 0) { 
        // try { dtmfTone.play(); } catch (e) { } 
        // } 
        } 
    }
 
  }

  /**
   * SIP 堆栈监听事件
   * @param e
   */
  function sipEventsListener(e) {
    console.log('- sip event: ', e, e.type);
    switch (e.type) {
      case 'started':
        self.register();
        break;
      case 'stopping': case 'stopped': case 'failed_to_start': case 'failed_to_stop':
        console.log('Disconnected Unexpected Error')
        sipStack = null;
        registerSession = null;
        callSession = null;
        
        break;
      case 'i_new_call': {
        console.log('i_new_call')
        if (callSession) {
          // do not accept the incoming call if we're already 'in call'
          e.newSession.hangup(); // comment this line for multi-line support
        } else{
          console.log('i_new_call----');
          callSession = e.newSession;
          // start listening for events
          callSession.setConfiguration(oConfigCall);
          // callSession.accept(oConfigCall);
        }
        
        break;
      }
      case 'm_permission_requested':
      {
        console.log('m_permission_requested');
        break;
      }
      case 'm_permission_accepted':
      case 'm_permission_refused':
      {
        //console.log('Microphone access is denied')
        if (e.type == 'm_permission_refused') {
          console.log('Media stream permission denied');
        }
        break;
      }
      case 'starting':
      default:
        break;
    }
    self.onEvent(e)
  }

  function engineReadyCb(e) {
    createSipStack();
  }

  function engineErrorCb(e) {
    console.log(e);
  }

  function createSipStack() {
    console.log('sipml的密码', password)
    sipStack = new SIPml.Stack({
      realm: serverUrl,
      impi: txtPrivateIdentity,
      impu: txtPublicIdentity,
      password: password,
      display_name: name,
      enable_rtcweb_breaker: true,
      websocket_proxy_url: wssUrl,
      outbound_proxy_url: udpUrl,
      ice_servers: stunServers,
      events_listener: {
        events: '*',
        listener: sipEventsListener
      },
      sip_headers: [
        {name: 'User-Agent', value: 'WebRTC-Phone sipML'},
        { name: 'Organization', value: 'Doubango Telecom' }
      ]
    });
    if (sipStack.start() != 0) {
      console.log('Failed to start the SIP stack');
    }
  }



  // Callback function for SIP sessions (INVITE, REGISTER, MESSAGE...)
  /* SIPml.Session.Event */
  function onSipEventSession(e) {
    console.log('==session event = ' + e.type);
    switch (e.type) {
      case 'connecting':
      case 'connected': {
        
        break;
      } // 'connecting' | 'connected'
      case 'terminating':
      case 'terminated': {
        if (e.session == registerSession) {
          callSession = null;
          registerSession = null;
        } else if (e.session == callSession) {

           callSession = null;
        }
        
        break;
      } // 'terminating' | 'terminated'

      case 'm_stream_video_local_added': {
        if (e.session == callSession) {
        }
        
        break;
      }
      case 'm_stream_video_local_removed': {
        if (e.session == callSession) {
        }
        
        break;
      }
      case 'm_stream_video_remote_added': {
        if (e.session == callSession) {
        }
        
        break;
      }
      case 'm_stream_video_remote_removed': {
        if (e.session == callSession) {
        }
        
        break;
      }

      case 'm_stream_audio_local_added':
      case 'm_stream_audio_local_removed':
      case 'm_stream_audio_remote_added':
      case 'm_stream_audio_remote_removed': {
        
        break;
      }

      case 'i_ect_new_call': {
        oSipSessionTransferCall = e.session;
        
        break;
      }

      case 'i_ao_request': {
        if (e.session == callSession) {
          var iSipResponseCode = e.getSipResponseCode();
          if (iSipResponseCode == 180 || iSipResponseCode == 183) {

          }
        }
        
        break;
      }

      case 'm_early_media': {
        if (e.session == callSession) {

        }
        
        break;
      }

      case 'm_local_hold_ok': {
        if (e.session == callSession) {
          if (callSession.bTransfering) {
            callSession.bTransfering = false;
            //this.AVSession.TransferCall(this.transferUri);
          }
        }
        
        break;
      }
      case 'm_local_hold_nok': {
        if (e.session == callSession) {
          callSession.bTransfering = false;
        }
        
        break;
      }
      case 'm_local_resume_ok': {
        if (e.session == callSession) {
          callSession.bTransfering = false;
          callSession.bHeld = false;

          if (SIPml.isWebRtc4AllSupported()) { // IE don't provide stream callback yet

          }
        }
        
        break;
      }
      case 'm_local_resume_nok': {
        if (e.session == callSession) {
          callSession.bTransfering = false;
        }
        
        break;
      }
      case 'm_remote_hold': {
        if (e.session == callSession) {
        }
        
        break;
      }
      case 'm_remote_resume': {
        if (e.session == callSession) {
        }
        
        break;
      }
      case 'm_bfcp_info': {
        if (e.session == callSession) {
        }
        
        break;
      }

      case 'o_ect_trying': {
        if (e.session == callSession) {
        }
        
        break;
      }
      case 'o_ect_accepted': {
        if (e.session == callSession) {
        }
        
        break;
      }
      case 'o_ect_completed':
      case 'i_ect_completed': {
        if (e.session == callSession) {
          if (oSipSessionTransferCall) {
            callSession = oSipSessionTransferCall;
          }
          oSipSessionTransferCall = null;
        }
        
        break;
      }
      case 'o_ect_failed':
      case 'i_ect_failed': {
        if (e.session == callSession) {
        }
        
        break;
      }
      case 'o_ect_notify':
      case 'i_ect_notify': {
        if (e.session == callSession) {
        }
        
        break;
      }
      case 'i_ect_requested': {
        if (e.session == callSession) {
          var s_message = "Do you accept call transfer to [" + e.getTransferDestinationFriendlyName() + "]?";//FIXME
          if (confirm(s_message)) {
            callSession.acceptTransfer();
            break;
          }
          callSession.rejectTransfer();
        }
        
        break;
      }
    }
    self.onEvent(e)
  }

  return webrtcPhone;

}))